<template>
    <div class="container">
      <h1>串口通信示例</h1>
      <button id="connect-btn" @click="connect">连接串口</button>
      <button id="disconnect-btn" @click="disconnect" :disabled="!port">断开连接</button>
      <div class="input-group">
        <input
          type="text"
          id="input-data"
          placeholder="输入要发送的数据"
          v-model="inputData"
          :disabled="!port"
        />
        <button id="send-btn" @click="sendData" :disabled="!port">发送</button>
      </div>
      <div class="output">
        <h2>接收数据：</h2>
        <pre id="output-data">{{ outputData }}</pre>
      </div>
    </div>
  </template>
  
  <script>
  import { ref } from 'vue';
  
  export default {
    setup() {
      const port = ref(null);
      const reader = ref(null);
      const writer = ref(null);
      const inputData = ref('');
      const outputData = ref('');
  
      const connect = async () => {
        if (!('serial' in navigator)) {
          alert('您的浏览器不支持 Web Serial API。');
          return;
        }
  
        try {
          port.value = await navigator.serial.requestPort();
          await port.value.open({ baudRate: 9600 });
  
          // 启用断开连接按钮和发送功能
          document.getElementById('disconnect-btn').disabled = false;
          document.getElementById('send-btn').disabled = false;
          document.getElementById('input-data').disabled = false;
          document.getElementById('connect-btn').disabled = true;
  
          // 开始读取数据
          readData();
        } catch (error) {
          alert('连接失败: ' + error.message);
        }
      };
  
      const disconnect = async () => {
        if (port.value) {
          try {
            // 取消读取操作
            if (reader.value) {
              await reader.value.cancel();
              await port.value.readable.getReader().releaseLock();
            }
  
            // 取消写入操作
            if (writer.value) {
              await writer.value.close();
              await port.value.writable.getWriter().releaseLock();
            }
  
            // 关闭串口
            await port.value.close();
            alert('已断开连接');
          } catch (error) {
            alert('断开连接失败: ' + error.message);
          } finally {
            // 重置界面
            document.getElementById('connect-btn').disabled = false;
            document.getElementById('disconnect-btn').disabled = true;
            document.getElementById('send-btn').disabled = true;
            document.getElementById('input-data').disabled = true;
            port.value = null;
            reader.value = null;
            writer.value = null;
          }
        }
      };
  
      const sendData = async () => {
        if (port.value && inputData.value) {
          try {
            writer.value = port.value.writable.getWriter();
            await writer.value.write(new TextEncoder().encode(inputData.value + '\n'));
            writer.value.releaseLock();
            writer.value = null;
            inputData.value = ''; // 清空输入框
          } catch (error) {
            console.error('发送数据失败:', error);
          }
        }
      };
  
      const readData = async () => {
        try {
          reader.value = port.value.readable.getReader();
          while (true) {
            const { value, done } = await reader.value.read();
            if (done) break;
            const text = new TextDecoder().decode(value);
            outputData.value += text + '\n';
          }
        } catch (error) {
          console.error('读取数据失败:', error);
        } finally {
          if (reader.value) {
            reader.value.releaseLock();
            reader.value = null;
          }
        }
      };
  
      return {
        port,
        reader,
        writer,
        inputData,
        outputData,
        connect,
        disconnect,
        sendData,
      };
    },
  };
  </script>
  
  <style scoped>
  body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
  }
  
  .container {
    background-color: #fff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    width: 400px;
    text-align: center;
  }
  
  h1 {
    margin-bottom: 20px;
  }
  
  button {
    padding: 10px 20px;
    margin: 5px;
    border: none;
    border-radius: 5px;
    background-color: #007bff;
    color: white;
    cursor: pointer;
  }
  
  button:disabled {
    background-color: #ccc;
    cursor: not-allowed;
  }
  
  .input-group {
    margin: 20px 0;
    display: flex;
    justify-content: space-between;
  }
  
  input {
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
    width: 70%;
  }
  
  .output {
    text-align: left;
    margin-top: 20px;
  }
  
  pre {
    background-color: #f8f9fa;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
    max-height: 200px;
    overflow-y: auto;
  }
  </style>